package cn.com.chengmandian.bike.controller;


import cn.com.chengmandian.agent.utils.AuthUtil;
import cn.com.chengmandian.agent.utils.ServletUtil;
import cn.com.chengmandian.bike.dto.MemberCardBuyForm;
import cn.com.chengmandian.bike.dto.MemberCardDto;
import cn.com.chengmandian.bike.log.ActionLog;
import cn.com.chengmandian.bike.model.*;
import cn.com.chengmandian.bike.model.vo.MemberCardVo;
import cn.com.chengmandian.bike.service.*;
import cn.com.chengmandian.bike.utils.AliPayUtil;
import cn.com.chengmandian.bike.utils.WxPayUtil;
import cn.com.chengmandian.core.db.pojo.PageData;
import cn.com.chengmandian.core.web.pojo.AgentInfo;
import cn.com.chengmandian.core.web.pojo.AgentUser;
import cn.com.chengmandian.core.web.pojo.AjaxResult;
import cn.com.chengmandian.core.web.utils.LocalMapUtil;
import cn.com.chengmandian.service.bike.BikePayClient;
import cn.com.chengmandian.service.bike.constants.CardPayStatusEnum;
import cn.com.chengmandian.service.bike.constants.ChannelTypeEnum;
import cn.com.chengmandian.service.bike.constants.MemberPayBusinessTypeEnum;
import cn.com.chengmandian.service.bike.constants.PayChannelEnum;
import cn.com.chengmandian.service.bike.form.BikePayForm;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 电单车运营平台骑行卡记录 前端控制器
 * </p>
 *
 * @author AutoGenerator
 * @since 2021-12-15
 */
@Api(tags = "用户骑行卡相关接口")
@RestController
@RequestMapping("/member/card")
public class EbMemberCardController {
    @Autowired
    private IEbMemberCardService memberCardService;

    @Autowired
    private IEbCardInfoService cardInfoService;

    @Autowired
    private IEbMemberPayService memberPayService;

    @Autowired
    private IEbMemberInfoService memberInfoService;

    @Autowired
    private IEbMemberWalletService memberWalletService;

    @Autowired
    private IEbAgentInfoService agentInfoService;

    @Autowired
    private IEbPayAccountService payAccountService;

    @Autowired
    private IEbRideOrderService rideOrderService;

    @Autowired
    private BikePayClient payClient;

    @Autowired
    private IEbIdentityAuthService identityAuthService;

    @ApiOperation("用户历史骑行卡列表")
    @GetMapping("/pages")
    public AjaxResult<PageData<MemberCardVo>> pages(MemberCardDto memberCardDto) {
        AgentInfo agentInfo = LocalMapUtil.getAgentInfo();
        Assert.notNull(agentInfo.getAreaId(), "缺少运营区ID");
        memberCardDto.setAreaId(agentInfo.getAreaId());
        return AjaxResult.success(PageData.build(memberCardService.pages(memberCardDto, AuthUtil.getAgentUser().getId())));
    }

    @ApiOperation("详情")
    @GetMapping("/detail/{id}")
    public AjaxResult<MemberCardVo> detail(@PathVariable("id") Integer id){
        return AjaxResult.success(memberCardService.detail(id));
    }

    @ApiOperation("用户可用骑行卡信息")
    @GetMapping("/available")
    public AjaxResult<MemberCardVo> available(){
        AgentInfo agentInfo = LocalMapUtil.getAgentInfo();
        Assert.notNull(agentInfo.getAreaId(), "缺少运营区ID");
        AgentUser agentUser = AuthUtil.getAgentUser();
        return AjaxResult.success(memberCardService.getMemberAvailableRecord(agentInfo.getAreaId(), agentUser.getId()));
    }

    @ApiOperation("购买骑行卡")
    @PostMapping("/buy")
    @ActionLog(name="购买骑行卡",description = "'参数：' + #memberCardBuyForm")
    public AjaxResult buy(@RequestBody MemberCardBuyForm memberCardBuyForm) throws Exception{
        Assert.notNull(memberCardBuyForm.getCardId(), "请选择骑行卡");
        Assert.notNull(memberCardBuyForm.getPayChannel(), "请选择充值渠道");
        EbCardInfo cardInfo = cardInfoService.getInfo(memberCardBuyForm.getCardId());
        Assert.notNull(cardInfo, "不存在的骑行卡");
        Integer memberId = AuthUtil.getAgentUser().getId();

        // 身份要求
        if(StrUtil.isNotBlank(cardInfo.getIdentityLimit())) {
            List<Integer> identityInfoIds = Arrays.asList(cardInfo.getIdentityLimit().split(",")).stream().filter(item-> StrUtil.isNotBlank(item)).map(item-> Integer.valueOf(item)).collect(Collectors.toList());
            if(ArrayUtil.isAllNotEmpty(identityInfoIds)) {
                identityAuthService.memberAuth(memberId, identityInfoIds);
            }
        }

        if (memberCardBuyForm.getPayChannel().equals(PayChannelEnum.WALLET.getCode())) {
            EbMemberWallet memberWallet = memberWalletService.getMemberWallet(memberId);
            if (memberWallet.getChargeMoney().compareTo(cardInfo.getPrice()) < 0) {
                return AjaxResult.error("钱包充值余额不足");
            }
        }
        MemberCardVo memberCardVo = memberCardService.getMemberAvailableRecord(cardInfo.getAreaId(), memberId);
        if(memberCardVo != null){
            Assert.isTrue(ObjectUtil.isNotNull(memberCardVo.getPayStatus()) && memberCardVo.getPayStatus().equals(CardPayStatusEnum.REFUND.getCode()),"存在生效中的骑行卡，无法再次购买");
        }

        EbMemberInfo memberInfo = memberInfoService.getById(memberId);

        JSONObject businessData = new JSONObject();
        // 获取用户最后一笔未使用骑行卡的待支付订单消耗骑行卡
        EbRideOrder rideOrder = rideOrderService.getNoUseCardWaitPayOrder(memberInfo.getId());
        if(rideOrder != null) {
            businessData.put("rideOrderId", rideOrder.getId());
        }

        AgentInfo agentInfo = LocalMapUtil.getAgentInfo();
        EbAgentInfo info = agentInfoService.getById(agentInfo.getId());
        if (info.getPayAccountId() != null) {
            EbPayAccount payAccount = payAccountService.getPayAccount(info.getPayAccountId(), memberId);
            if (payAccount != null && (memberCardBuyForm.getPayChannel().equals(PayChannelEnum.WXPAY.getCode()) || memberCardBuyForm.getPayChannel().equals(PayChannelEnum.ALIPAY.getCode()))) {
                PayChannelEnum payChannel = PayChannelEnum.getByCode(memberCardBuyForm.getPayChannel());
                BikePayForm form = new BikePayForm();
                form.setPayBusinessType(MemberPayBusinessTypeEnum.CARD);
                form.setPayChannel(payChannel);
                form.setMoney(cardInfo.getPrice());
                form.setOpenId(StrUtil.isNotBlank(memberCardBuyForm.getOpenId()) ? memberCardBuyForm.getOpenId() : memberInfo.getOpenId());
                form.setAlipayUserId(memberInfo.getAlipayUserId());
                form.setAlipayOpenId(memberInfo.getAlipayOpenId());
                form.setAreaId(agentInfo.getAreaId());
                form.setMemberId(AuthUtil.getAgentUser().getId());
                form.setBusinessId(cardInfo.getId());
                form.setClientIp(ServletUtil.getIp());
                form.setBusinessData(businessData.toJSONString());
                return payClient.pay(agentInfo.getId(), form);
            }
        }

        EbMemberPay memberPay = memberPayService.createPay(cardInfo.getAreaId(), AuthUtil.getAgentUser().getId(), MemberPayBusinessTypeEnum.CARD, cardInfo.getId(),
                cardInfo.getPrice(), memberCardBuyForm.getPayChannel(), businessData.toJSONString());

        String notifyUrl = "http://"+ agentInfo.getDomain() + "/api/v1/bikeuser/notify";

        if (memberCardBuyForm.getPayChannel().equals(PayChannelEnum.WXPAY.getCode())) {
            Assert.isTrue(StrUtil.isNotBlank(agentInfo.getWxMchId()), "未开启微信支付");
            if (memberCardBuyForm.getChannelType().equals(ChannelTypeEnum.MINI.getCode())) {
                String openId = StrUtil.isNotBlank(memberCardBuyForm.getOpenId()) ? memberCardBuyForm.getOpenId() : memberInfo.getOpenId();
                Assert.isTrue(StrUtil.isNotBlank(openId), "缺少openid");
                return AjaxResult.success(WxPayUtil.jsapiTransactions(
                        agentInfo.getWxMiniAppid(),
                        agentInfo.getWxMchId(),
                        openId,
                        "用户购买骑行卡",
                        memberPay.getPayNo(),
                        memberPay.getMoney(),
                        agentInfo.getWxKeyPath(),
                        agentInfo.getWxCertPath(),
                        notifyUrl + "/wxpay/pay/" + LocalMapUtil.getAgentInfo().getAgentNo()
                ));
            }
        } else if (memberCardBuyForm.getPayChannel().equals(PayChannelEnum.ALIPAY.getCode())) {
            // 支付宝用户唯一标识user_id 和open_id必须有一个有值
            Assert.isTrue(StrUtil.isNotBlank(memberInfo.getAlipayUserId()) || StrUtil.isNotBlank(memberInfo.getAlipayOpenId()), "用户缺少支付宝用户标识");
            return AjaxResult.success(AliPayUtil.getTradeCreateRequestParam(
                    agentInfo.getAliMiniAppid(),
                    memberInfo.getAlipayUserId(),
                    memberInfo.getAlipayOpenId(),
                    "用户购买骑行卡",
                    memberPay.getPayNo(),
                    memberPay.getMoney(),
                    agentInfo.getAliPayPrivateKey(),
                    agentInfo.getAliPayCertPath(),
                    agentInfo.getAliPayPublicCertPath(),
                    agentInfo.getAliPayRootCertPath(),
                    notifyUrl + "/ali/pay/" + LocalMapUtil.getAgentInfo().getAgentNo()
            ));
        } else if (memberCardBuyForm.getPayChannel().equals(PayChannelEnum.WALLET.getCode())) {
            memberPayService.paySuccessByPay(memberPay, null);
            return AjaxResult.success("购买成功");
        }
        return AjaxResult.error("不支持的支付方式！");
    }
}
